/***************************************************************************
   Filename:    Game.h
   Author:      Josh Partridge
   Description: Contains actual breakout game (Game class)
****************************************************************************/

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

#include "Brush.h"
#include "StateMachine.h"
#include "Brick.h"
#include "helpers.h"
#include "boxgen.h"
#include "Paddle.h"
#include "Ball.h"
#include <stdlib.h>
#include <time.h>
#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>
#include <vector>

// frames per second
const int FPS = 30;

class Game{
    private:
        //pointer to main's StateMachine so we can state from here
        StateMachine* stateMachine;
        //pointer to main's brush
        Brush* brush;
        Paddle paddle;
        Ball ball;
        //holds all of the level's bricks
        std::vector<Brick> bricks;

        //player score
        unsigned int score;
        //score as of the last time this method was called
        unsigned int prevScore;

        //when this level is completed, player will reach "win" screen
        int finalLevel;
        //current level
        int level;
        //current number of lives remaining, 0 means game over
        int lives;
        // true if game was paused, false if just advancing to next level
        bool returning;

        //when the paddle is moved we update it (this becomse true)
        bool updatePaddle;

        /************************************************************************************
         Name:               display
         Description:        Redraws the paddle and ball, and debug information (ball angle
                             and current score if left CTRL is held down.
        *************************************************************************************/
        void display();

        /************************************************************************************
         Name:               handleInput
         Description:        Sets paddle acceleration and allows user to return to menu with ESC
        *************************************************************************************/
        void handleInput();

        /************************************************************************************
         Name:               drawScore
         Description:        Displays current score in bottom right corner of screen
        *************************************************************************************/
        void drawScore();

        /************************************************************************************
         Name:               saveScore
         Description:        Displays scoreboard with player's score inserted if player places
                             in the top ten. Also calls getPlayerName if this is the case.
        *************************************************************************************/
        void saveScore();

        /************************************************************************************
         Name:               tallyScore
         Description:        Displays points gained from previous levels (applies bonuses etc)
        *************************************************************************************/
        void tallyScore();

        /************************************************************************************
         Name:               generateLevel
         Description:        Populates the bricks vector depending on level number and a degree
                             of chance (weighted random numbers).
        *************************************************************************************/
        void generateLevel();


        /************************************************************************************
         Name:               drawLevel
         Description:        called only at the beginning of Game.run(), this draws the bricks
                             to the screen.
        *************************************************************************************/
        void drawLevel();

        /************************************************************************************
         Name:               levelIntro
         Description:        displays level # or provides intro to boss level(s)
        *************************************************************************************/
        void levelIntro();

        /************************************************************************************
         Name:               generateBrick
         Description:        sets health and color for a brick (semi random)
         Input:
                      brick: reference of the brick to be modified
        *************************************************************************************/
        void generateBrick(Brick& brick);

        /************************************************************************************
         Name:               getPlayerName
         Description:        accepts an 8 letter name to insert into the scoreboard
         Input:
                      place: player's place on the scoreboard(1 - 10)
         Output:
                     string: the final name
        *************************************************************************************/
        std::string getPlayerName(int place);

    public:

        /************************************************************************************
         Name:               Game - constructor
         Description:        initializes Game's attributes
         Input:
                      state: pointer to main's StateMachine
                   theBrush: pointer to main's Brush
        *************************************************************************************/
        Game(StateMachine *state, Brush *theBrush);

        /************************************************************************************
         Name:               run
         Description:        resets level & displays level # if new level, contains game loop
        *************************************************************************************/
        void run();

        /************************************************************************************
         Name:               getLives
         Description:        getter for lives
         Output:
                     return: int representing number of lives remaining
        *************************************************************************************/
        int getLives();
};

#endif // GAME_H_INCLUDED
